package zgrjb.snbq.teach_platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import zgrjb.snbq.teach_platform.dto.model.TaskQueueDO;
import zgrjb.snbq.teach_platform.mapper.TaskQueueMapper;
import zgrjb.snbq.teach_platform.service.NotificationService;
import zgrjb.snbq.teach_platform.service.TaskQueueService;
import zgrjb.snbq.teach_platform.util.IDUtil;
import zgrjb.snbq.teach_platform.util.JsonData;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 任务队列服务实现类
 * 
 * @author system
 * @since 2024-12-28
 */
@Slf4j
@Service
public class TaskQueueServiceImpl implements TaskQueueService {

    @Autowired
    private TaskQueueMapper taskQueueMapper;

    @Autowired
    private NotificationService notificationService;

    @Override
    @Transactional
    public JsonData createTask(Long userId, String taskType, String title, String description,
                              Long sourceId, String sourceType, Integer priority) {
        try {
            TaskQueueDO task = TaskQueueDO.builder()
                .id((Long) IDUtil.geneSnowFlakeID())
                .userId(userId)
                .taskType(taskType)
                .title(title)
                .description(description)
                .sourceId(sourceId)
                .sourceType(sourceType)
                .priority(priority != null ? priority : 2)
                .status(1) // 待处理
                .reminderCount(0)
                .autoGenerated(0) // 手动创建
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();

            taskQueueMapper.insert(task);

            // 创建对应通知
            notificationService.createTaskNotification(userId, 
                "新任务：" + title, 
                description, 
                sourceId, 
                sourceType);

            log.info("创建任务成功，任务ID: {}", task.getId());
            return JsonData.buildSuccess(task);

        } catch (Exception e) {
            log.error("创建任务失败", e);
            return JsonData.buildError("创建任务失败");
        }
    }

    @Override
    public JsonData getUserTasks(Long userId, String taskType, Integer status, int page, int size) {
        try {
            Page<TaskQueueDO> pageParam = new Page<>(page, size);
            QueryWrapper<TaskQueueDO> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId);
            
            if (taskType != null && !taskType.isEmpty()) {
                wrapper.eq("task_type", taskType);
            }
            
            if (status != null) {
                wrapper.eq("status", status);
            }
            
            wrapper.orderByDesc("priority", "create_time");

            IPage<TaskQueueDO> result = taskQueueMapper.selectPage(pageParam, wrapper);

            Map<String, Object> data = new HashMap<>();
            data.put("list", result.getRecords());
            data.put("total", result.getTotal());
            data.put("current", result.getCurrent());
            data.put("size", result.getSize());

            return JsonData.buildSuccess(data);

        } catch (Exception e) {
            log.error("获取用户任务失败", e);
            return JsonData.buildError("获取任务失败");
        }
    }

    @Override
    @Transactional
    public JsonData updateTaskStatus(Long taskId, Integer status, Long userId) {
        try {
            TaskQueueDO task = taskQueueMapper.selectById(taskId);
            if (task == null || !task.getUserId().equals(userId)) {
                return JsonData.buildError("任务不存在或无权限");
            }

            task.setStatus(status);
            task.setUpdateTime(LocalDateTime.now());
            
            if (status == 3) { // 已完成
                task.setCompletionTime(LocalDateTime.now());
            }

            taskQueueMapper.updateById(task);

            return JsonData.buildSuccess("任务状态更新成功");

        } catch (Exception e) {
            log.error("更新任务状态失败", e);
            return JsonData.buildError("更新任务状态失败");
        }
    }

    @Override
    @Transactional
    public JsonData completeTask(Long taskId, Long userId) {
        return updateTaskStatus(taskId, 3, userId);
    }

    @Override
    public JsonData getTaskStatistics(Long userId) {
        try {
            Map<String, Object> statistics = new HashMap<>();

            // 待处理任务数量
            QueryWrapper<TaskQueueDO> pendingWrapper = new QueryWrapper<>();
            pendingWrapper.eq("user_id", userId).eq("status", 1);
            Long pending = taskQueueMapper.selectCount(pendingWrapper);
            statistics.put("pending", pending);

            // 进行中任务数量
            QueryWrapper<TaskQueueDO> processingWrapper = new QueryWrapper<>();
            processingWrapper.eq("user_id", userId).eq("status", 2);
            Long processing = taskQueueMapper.selectCount(processingWrapper);
            statistics.put("processing", processing);

            // 已完成任务数量
            QueryWrapper<TaskQueueDO> completedWrapper = new QueryWrapper<>();
            completedWrapper.eq("user_id", userId).eq("status", 3);
            Long completed = taskQueueMapper.selectCount(completedWrapper);
            statistics.put("completed", completed);

            // 过期任务数量
            QueryWrapper<TaskQueueDO> expiredWrapper = new QueryWrapper<>();
            expiredWrapper.eq("user_id", userId).eq("status", 4);
            Long expired = taskQueueMapper.selectCount(expiredWrapper);
            statistics.put("expired", expired);

            // 即将到期任务数量（3天内）
            LocalDateTime threeDaysLater = LocalDateTime.now().plusDays(3);
            QueryWrapper<TaskQueueDO> upcomingWrapper = new QueryWrapper<>();
            upcomingWrapper.eq("user_id", userId)
                          .in("status", 1, 2)
                          .le("due_time", threeDaysLater)
                          .ge("due_time", LocalDateTime.now());
            Long upcoming = taskQueueMapper.selectCount(upcomingWrapper);
            statistics.put("upcoming", upcoming);

            return JsonData.buildSuccess(statistics);

        } catch (Exception e) {
            log.error("获取任务统计失败", e);
            return JsonData.buildError("获取任务统计失败");
        }
    }

    @Override
    public JsonData getUpcomingTasks(Long userId, int days) {
        try {
            LocalDateTime deadline = LocalDateTime.now().plusDays(days);
            
            QueryWrapper<TaskQueueDO> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId)
                   .in("status", 1, 2)
                   .le("due_time", deadline)
                   .ge("due_time", LocalDateTime.now())
                   .orderByAsc("due_time");

            List<TaskQueueDO> upcomingTasks = taskQueueMapper.selectList(wrapper);

            return JsonData.buildSuccess(upcomingTasks);

        } catch (Exception e) {
            log.error("获取即将到期任务失败", e);
            return JsonData.buildError("获取即将到期任务失败");
        }
    }

    @Override
    @Transactional
    public JsonData autoGenerateGradingTasks(Long examId) {
        try {
            // TODO: 根据考试ID获取相关信息，为教师自动创建批改任务
            // 这里暂时返回成功，后续实现具体逻辑
            log.info("为考试{}自动生成批改任务", examId);
            return JsonData.buildSuccess("自动生成批改任务成功");

        } catch (Exception e) {
            log.error("自动生成批改任务失败", e);
            return JsonData.buildError("自动生成批改任务失败");
        }
    }

    @Override
    @Transactional
    public JsonData cleanExpiredTasks() {
        try {
            // 将过期任务状态更新为过期
            LocalDateTime now = LocalDateTime.now();
            QueryWrapper<TaskQueueDO> wrapper = new QueryWrapper<>();
            wrapper.in("status", 1, 2)
                   .lt("due_time", now);

            TaskQueueDO updateTask = new TaskQueueDO();
            updateTask.setStatus(4); // 已过期
            updateTask.setUpdateTime(now);

            int updated = taskQueueMapper.update(updateTask, wrapper);
            
            log.info("清理过期任务，共更新{}条记录", updated);
            return JsonData.buildSuccess("清理了 " + updated + " 个过期任务");

        } catch (Exception e) {
            log.error("清理过期任务失败", e);
            return JsonData.buildError("清理过期任务失败");
        }
    }

    @Override
    public JsonData getTaskDetail(Long taskId, Long userId) {
        try {
            TaskQueueDO task = taskQueueMapper.selectById(taskId);
            if (task == null || !task.getUserId().equals(userId)) {
                return JsonData.buildError("任务不存在或无权限");
            }

            // 可以在这里添加更多任务详情信息
            Map<String, Object> taskDetail = new HashMap<>();
            taskDetail.put("task", task);
            taskDetail.put("statusText", getStatusText(task.getStatus()));
            taskDetail.put("priorityText", getPriorityText(task.getPriority()));
            taskDetail.put("isOverdue", task.getDueTime() != null && task.getDueTime().isBefore(LocalDateTime.now()));

            return JsonData.buildSuccess(taskDetail);

        } catch (Exception e) {
            log.error("获取任务详情失败", e);
            return JsonData.buildError("获取任务详情失败");
        }
    }

    /**
     * 获取状态文本
     */
    private String getStatusText(Integer status) {
        switch (status) {
            case 1: return "待处理";
            case 2: return "进行中";
            case 3: return "已完成";
            case 4: return "已过期";
            default: return "未知状态";
        }
    }

    /**
     * 获取优先级文本
     */
    private String getPriorityText(Integer priority) {
        switch (priority) {
            case 1: return "低";
            case 2: return "中";
            case 3: return "高";
            case 4: return "紧急";
            default: return "普通";
        }
    }
} 